package com.ruoyi.system.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.config.TenantConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.CommonWhether;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.LoginSysTenant;
import com.ruoyi.system.domain.SysTenant;
import com.ruoyi.system.domain.SysTenantPackage;
import com.ruoyi.system.domain.vo.SysTenantVo;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysTenantMapper;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysTenantPackageService;
import com.ruoyi.system.service.ISysTenantService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

import static com.ruoyi.common.utils.SecurityUtils.getUsername;

/**
 * 租户管理Service业务层处理
 *
 * @author fengcheng
 * @date 2025-01-06
 */
@Service
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements ISysTenantService {
    @Autowired
    private SysTenantMapper sysTenantMapper;

    @Autowired
    private TenantConfig tenantConfig;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysTenantPackageService sysTenantPackageService;

    @Autowired
    private SysDeptMapper deptMapper;

    @Autowired
    private ISysRoleService roleService;

    /**
     * 查询租户管理
     *
     * @param tenantId 租户管理主键
     * @return 租户管理
     */
    @Override
    public SysTenant selectSysTenantByTenantId(String tenantId) {
        return sysTenantMapper.selectSysTenantByTenantId(tenantId);
    }

    /**
     * 查询租户管理列表
     *
     * @param sysTenant 租户管理
     * @return 租户管理
     */
    @Override
    public List<SysTenant> selectSysTenantList(SysTenant sysTenant) {
        return sysTenantMapper.selectSysTenantList(sysTenant);
    }

    /**
     * 新增租户管理
     *
     * @param sysTenantVo 租户管理
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSysTenant(SysTenantVo sysTenantVo) {
        if (ObjectUtil.isNotNull(sysTenantMapper.selectSysTenantByCompanyName(sysTenantVo.getCompanyName()))) {
            throw new ServiceException(MessageUtils.message("tenant.companyName.exists"));
        }

        if (ObjectUtil.isNotNull(sysTenantMapper.selectSysTenantByContactPhone(sysTenantVo.getContactPhone()))) {
            throw new ServiceException(MessageUtils.message("tenant.contactPhone.exists"));
        }
        // 设置忽略租户插件
        InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());

        String tenantId = String.valueOf(IdUtil.getSnowflake().nextId());
        sysTenantVo.setTenantId(tenantId);

        // 新增部门
        Long deptId = insertDept(sysTenantVo);

        // 新增角色
        Long roleId = insertRole(sysTenantVo);

        // 新增租户管理员
        Long userId = insertUser(sysTenantVo, deptId, roleId);


        sysTenantVo.setCreateTime(DateUtils.getNowDate());
        sysTenantVo.setTenantUserId(userId);
        int i = sysTenantMapper.insertSysTenant(sysTenantVo);
        // 关闭忽略策略
        InterceptorIgnoreHelper.clearIgnoreStrategy();
        return i;
    }

    /**
     * 新增租户角色管理
     *
     * @param sysTenantVo 租户管理
     * @param deptId      部门id
     * @param roleId      角色id
     */
    private Long insertUser(SysTenantVo sysTenantVo, Long deptId, Long roleId) {
        // 新增租户超级管理员用户
        SysUser user = new SysUser();
        user.setCreateBy(getUsername());
        user.setPassword(SecurityUtils.encryptPassword(sysTenantVo.getPassword()));
        user.setTenantId(sysTenantVo.getTenantId());
        user.setUserName(sysTenantVo.getUserName());
        user.setDeptId(deptId);
        user.setRoleIds(new Long[]{roleId});
        user.setNickName(sysTenantVo.getCompanyName());
        user.setIsAdmin(CommonWhether.CORRECT.getCode());

        userService.insertUser(user);
        return user.getUserId();
    }

    /**
     * 新增租户角色管理
     *
     * @param sysTenantVo 租户管理
     * @return 角色id
     */
    private Long insertRole(SysTenantVo sysTenantVo) {
        SysRole role = new SysRole();
        role.setTenantId(sysTenantVo.getTenantId());
        role.setRoleName("超级管理员");
        role.setRoleKey("admin");
        role.setCreateBy(getUsername());
        role.setIsAdmin(CommonWhether.CORRECT.getCode());

        SysTenantPackage sysTenantPackage = sysTenantPackageService.selectSysTenantPackageByTenantPackageId(sysTenantVo.getTenantPackageId());
        role.setMenuIds(Arrays.stream(sysTenantPackage.getMenuIds().split(","))
                .map(Long::parseLong)
                .toArray(Long[]::new));
        roleService.insertRole(role);
        return role.getRoleId();
    }

    /**
     * 新增租户部门管理
     *
     * @param sysTenantVo 租户管理
     * @return 部门id
     */
    private Long insertDept(SysTenantVo sysTenantVo) {
        SysDept dept = new SysDept();
        dept.setTenantId(sysTenantVo.getTenantId());
        dept.setDeptName(sysTenantVo.getCompanyName());
        dept.setLeader(sysTenantVo.getContactUserName());
        dept.setPhone(sysTenantVo.getContactPhone());
        dept.setCreateBy(getUsername());
        dept.setIsAdmin(CommonWhether.CORRECT.getCode());
        deptMapper.insertDept(dept);
        return dept.getDeptId();
    }

    /**
     * 修改租户管理
     *
     * @param sysTenantVo 租户管理
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSysTenant(SysTenantVo sysTenantVo) {
        sysTenantVo.setUpdateTime(DateUtils.getNowDate());

        // 设置忽略租户插件
        InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());

        SysUser sysUser = userService.selectUserByIdAndTenantId(sysTenantVo.getTenantUserId(), sysTenantVo.getTenantId());

        SysRole role = new SysRole();
        role.setTenantId(sysTenantVo.getTenantId());
        role.setRoleId(sysUser.getRoles().get(0).getRoleId());
        SysTenantPackage sysTenantPackage = sysTenantPackageService.selectSysTenantPackageByTenantPackageId(sysTenantVo.getTenantPackageId());
        role.setMenuIds(Arrays.stream(sysTenantPackage.getMenuIds().split(","))
                .map(Long::parseLong)
                .toArray(Long[]::new));
        roleService.updateRole(role);

        // 关闭忽略策略
        InterceptorIgnoreHelper.clearIgnoreStrategy();

        return sysTenantMapper.updateSysTenant(sysTenantVo);
    }

    /**
     * 批量删除租户管理
     *
     * @param tenantIds 需要删除的租户管理主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteSysTenantByTenantIds(String[] tenantIds) {
        for (String tenantId : tenantIds) {
            if (tenantId.equals(tenantConfig.getDefaultTenantId())) {
                throw new RuntimeException(MessageUtils.message("tenant.default"));
            }
        }
        return sysTenantMapper.deleteSysTenantByTenantIds(tenantIds);
    }

    /**
     * 删除租户管理信息
     *
     * @param tenantId 租户管理主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteSysTenantByTenantId(String tenantId) {
        if (tenantId.equals(tenantConfig.getDefaultTenantId())) {
            throw new RuntimeException(MessageUtils.message("tenant.default"));
        }
        return sysTenantMapper.deleteSysTenantByTenantId(tenantId);
    }

    /**
     * 查询登录租户管理列表（不分页）
     *
     * @return 结果
     */
    @Override
    public List<LoginSysTenant> loginSysTenantList() {
        return sysTenantMapper.loginSysTenantList();
    }

    /**
     * 重置租户密码
     *
     * @param tenantId 租户ID
     * @param password 密码
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int resetTenantPwd(String tenantId, String password) {
        SysTenant sysTenant = sysTenantMapper.selectSysTenantByTenantId(tenantId);
        // 设置忽略租户插件
        InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());
        SysUser user = new SysUser();
        user.setUserId(sysTenant.getTenantUserId());
        user.setPassword(SecurityUtils.encryptPassword(password));
        user.setTenantId(tenantId);
        int i = userService.resetTenantPwd(user);

        // 关闭忽略策略
        InterceptorIgnoreHelper.clearIgnoreStrategy();
        return i;
    }

    /**
     * 根据套餐ID查询租户信息列表
     *
     * @param tenantPackageId 套餐ID
     * @return 租户信息列表
     */
    @Override
    public List<SysTenantVo> selectSysTenantListByTenantPackageId(Long tenantPackageId) {
        return sysTenantMapper.selectSysTenantListByTenantPackageId(tenantPackageId);
    }

    /**
     * 根据套餐ID查询租户信息数量
     *
     * @param tenantPackageId 套餐ID
     * @return 租户信息数量
     */
    @Override
    public int selectSysTenantByTenantPackageId(Long tenantPackageId) {
        return sysTenantMapper.selectSysTenantByTenantPackageId(tenantPackageId);
    }
}
